package service

import (
	"context"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"log"
	"mts/trans_srv/internal/domain"
	"mts/trans_srv/internal/repository"
	"mts/trans_srv/utils/rabbitmq"
	"time"
)

type ElementService interface {
	FindElementByID(ctx context.Context, id string) (domain.Element, error)
	FindAll(ctx context.Context) ([]domain.Element, error)
	List(ctx context.Context, page, pageSize int) ([]domain.Element, error)
	DeleteById(ctx context.Context, id string) error
	EditById(ctx context.Context, id string, element domain.Element) error
	Insert(ctx context.Context, element domain.CreateElement) error
	CheckExistByElementName(ctx context.Context, name string) (*bool, error)
	GetCustomFormattedTranslations(ctx context.Context, page, pageSize int) (*[]domain.TranslationElem, error)
	AddElementAndTranslation(ctx *gin.Context, info domain.CreateElementAndTranslationInfo) error
	GetListCount(ctx context.Context) (int, error)
	Publish(logData map[string]interface{}) error
}

type ElementServiceImpl struct {
	l   repository.LanguageRepository
	e   repository.ElementRepository
	t   repository.TranslationRepository
	rmq *rabbitmq.RabbitMQ
}

func (svc ElementServiceImpl) GetListCount(ctx context.Context) (int, error) {
	return svc.e.GetListCount(ctx)
}

// AddElementAndTranslation 添加组件和翻译
func (svc ElementServiceImpl) AddElementAndTranslation(ctx *gin.Context, info domain.CreateElementAndTranslationInfo) error {
	if err := svc.e.Save(ctx, info); err != nil {
		log.Fatal("添加组件失败")
		return err
	}
	return nil
}

func NewElementService(l repository.LanguageRepository, e repository.ElementRepository, t repository.TranslationRepository, rmq *rabbitmq.RabbitMQ) ElementService {
	return &ElementServiceImpl{
		l:   l,
		e:   e,
		t:   t,
		rmq: rmq,
	}
}

func (svc ElementServiceImpl) FindElementByID(ctx context.Context, id string) (domain.Element, error) {
	element, err := svc.e.FindElementByID(ctx, id)
	if err != nil {
		return domain.Element{}, err
	}

	return element, nil
}

func (svc ElementServiceImpl) List(ctx context.Context, page, pageSize int) ([]domain.Element, error) {
	elements, err := svc.e.List(ctx, page, pageSize)
	if err != nil {
		return nil, err
	}
	return elements, err
}
func (svc ElementServiceImpl) FindAll(ctx context.Context) ([]domain.Element, error) {
	elements, err := svc.e.FindAll(ctx)
	if err != nil {
		return nil, err
	}
	return elements, err
}
func (svc ElementServiceImpl) DeleteById(ctx context.Context, id string) error {
	if err := svc.e.DeleteById(ctx, id); err != nil {
		return err
	}
	return nil
}

func (svc ElementServiceImpl) EditById(ctx context.Context, id string, element domain.Element) error {
	if err := svc.e.EditById(ctx, id, element); err != nil {
		return err
	}
	return nil
}

func (svc ElementServiceImpl) Insert(ctx context.Context, element domain.CreateElement) error {
	elementInfo := domain.Element{
		Name:        element.Name,
		Type:        element.Type,
		Description: element.Description,
	}
	if err := svc.e.Insert(ctx, elementInfo); err != nil {
		return err
	}
	return nil
}

func (svc ElementServiceImpl) CheckExistByElementName(ctx context.Context, name string) (*bool, error) {
	if isExist, err := svc.e.CheckExistByElementName(ctx, name); err != nil {
		return nil, err
	} else {
		return &isExist, nil
	}
}

// GetCustomFormattedTranslations 后端管理界面提供所有组件与翻译相关信息
func (svc ElementServiceImpl) GetCustomFormattedTranslations(ctx context.Context, page, pageSize int) (*[]domain.TranslationElem, error) {
	var elements []domain.Element
	var err error
	if page == 0 && pageSize == 0 {
		elements, err = svc.e.FindAll(ctx)
		if err != nil {
			return nil, err
		}
	} else {
		elements, err = svc.e.List(ctx, page, pageSize)
		if err != nil {
			return nil, err
		}
	}

	var ids []string
	for _, ele := range elements {
		ids = append(ids, ele.ID)
	}
	trans, err := svc.t.GetAllTranslationWithElementsId(ctx, ids...)
	if err != nil {
		return nil, err
	}
	var transistor []domain.TranslationElem
	for _, v := range elements {
		var ele domain.TranslationElem
		ele.ID = v.ID
		ele.Name = v.Name
		ele.Type = v.Type
		ele.Description = v.Description
		ele.Translations = make(map[string]string)
		for _, item := range trans {
			if item.ElementID == v.ID {
				ele.Translations[item.Locale] = item.Content
			}
		}
		transistor = append(transistor, ele)
	}
	return &transistor, nil
}

func (svc ElementServiceImpl) Publish(logData map[string]interface{}) error {
	logData["timestamp"] = time.Now()
	err := svc.rmq.Publish(
		logData,
	)
	if err != nil {
		zap.S().Errorf("Error publishing log: %v", err)
		return err
	}
	return nil
}
